package com.example.baguwen.service.impl;

import com.example.baguwen.common.PageResult;
import com.example.baguwen.dto.BaguwenFavoriteDTO;
import com.example.baguwen.entity.Baguwen;
import com.example.baguwen.entity.BaguwenFavorite;
import com.example.baguwen.repository.BaguwenFavoriteRepository;
import com.example.baguwen.repository.BaguwenRepository;
import com.example.baguwen.service.BaguwenFavoriteService;
import com.example.baguwen.service.UserService;
import com.example.baguwen.vo.BaguwenFavoriteVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class BaguwenFavoriteServiceImpl implements BaguwenFavoriteService {

    @Autowired
    private BaguwenFavoriteRepository favoriteRepository;
    
    @Autowired
    private BaguwenRepository baguwenRepository;
    
    @Autowired
    private UserService userService;

    @Override
    @Transactional
    public BaguwenFavoriteVO add(BaguwenFavoriteDTO favoriteDTO) {
        // 获取当前用户ID
        Long userId = userService.getCurrentUserId();
        
        // 先检查八股文是否存在
        Baguwen baguwen = baguwenRepository.findById(favoriteDTO.getBaguwenId())
                .orElseThrow(() -> new EntityNotFoundException("八股文不存在，ID: " + favoriteDTO.getBaguwenId()));
        
        // 检查是否已经收藏过
        if (favoriteRepository.existsByUserIdAndBaguwenId(userId, favoriteDTO.getBaguwenId())) {
            throw new IllegalStateException("该八股文已经收藏过了");
        }
        
        // 创建收藏记录
        BaguwenFavorite favorite = new BaguwenFavorite();
        BeanUtils.copyProperties(favoriteDTO, favorite);
        favorite.setUserId(userId); // 设置用户ID
        
        // 保存收藏
        favorite = favoriteRepository.save(favorite);
        
        // 转换为VO并返回
        BaguwenFavoriteVO vo = new BaguwenFavoriteVO();
        BeanUtils.copyProperties(favorite, vo);
        vo.setBaguwen(baguwen);
        
        return vo;
    }

    @Override
    @Transactional
    public BaguwenFavoriteVO update(Long id, BaguwenFavoriteDTO favoriteDTO) {
        // 获取当前用户ID
        Long userId = userService.getCurrentUserId();
        
        // 查找收藏记录
        BaguwenFavorite favorite = favoriteRepository.findById(id)
                .orElseThrow(() -> new EntityNotFoundException("收藏记录不存在，ID: " + id));
        
        // 验证是否是当前用户的收藏
        if (!favorite.getUserId().equals(userId)) {
            throw new IllegalStateException("无权修改他人的收藏");
        }
        
        // 只更新备注字段
        favorite.setRemark(favoriteDTO.getRemark());
        
        // 保存更新
        favorite = favoriteRepository.save(favorite);
        
        // 获取对应的八股文
        BaguwenFavorite finalFavorite = favorite;
        Baguwen baguwen = baguwenRepository.findById(favorite.getBaguwenId())
                .orElseThrow(() -> new EntityNotFoundException("八股文不存在，ID: " + finalFavorite.getBaguwenId()));
        
        // 转换为VO并返回
        BaguwenFavoriteVO vo = new BaguwenFavoriteVO();
        BeanUtils.copyProperties(favorite, vo);
        vo.setBaguwen(baguwen);
        
        return vo;
    }

    @Override
    @Transactional
    public void delete(Long id) {
        // 获取当前用户ID
        Long userId = userService.getCurrentUserId();
        
        // 查找收藏记录
        BaguwenFavorite favorite = favoriteRepository.findById(id)
                .orElseThrow(() -> new EntityNotFoundException("收藏记录不存在，ID: " + id));
        
        // 验证是否是当前用户的收藏
        if (!favorite.getUserId().equals(userId)) {
            throw new IllegalStateException("无权删除他人的收藏");
        }
        
        favoriteRepository.deleteById(id);
    }

    @Override
    public BaguwenFavoriteVO getById(Long id) {
        // 获取当前用户ID
        Long userId = userService.getCurrentUserId();
        
        // 查找收藏记录
        BaguwenFavorite favorite = favoriteRepository.findById(id)
                .orElseThrow(() -> new EntityNotFoundException("收藏记录不存在，ID: " + id));
        
        // 验证是否是当前用户的收藏
        if (!favorite.getUserId().equals(userId)) {
            throw new IllegalStateException("无权查看他人的收藏");
        }
        
        // 获取对应的八股文
        Baguwen baguwen = baguwenRepository.findById(favorite.getBaguwenId())
                .orElseThrow(() -> new EntityNotFoundException("八股文不存在，ID: " + favorite.getBaguwenId()));
        
        // 转换为VO并返回
        BaguwenFavoriteVO vo = new BaguwenFavoriteVO();
        BeanUtils.copyProperties(favorite, vo);
        vo.setBaguwen(baguwen);
        
        return vo;
    }

    @Override
    public BaguwenFavoriteVO getByBaguwenId(Long baguwenId) {
        // 获取当前用户ID
        Long userId = userService.getCurrentUserId();
        
        // 查找收藏记录
        BaguwenFavorite favorite = favoriteRepository.findByUserIdAndBaguwenId(userId, baguwenId)
                .orElseThrow(() -> new EntityNotFoundException("该八股文未被收藏，ID: " + baguwenId));
        
        // 获取对应的八股文
        Baguwen baguwen = baguwenRepository.findById(baguwenId)
                .orElseThrow(() -> new EntityNotFoundException("八股文不存在，ID: " + baguwenId));
        
        // 转换为VO并返回
        BaguwenFavoriteVO vo = new BaguwenFavoriteVO();
        BeanUtils.copyProperties(favorite, vo);
        vo.setBaguwen(baguwen);
        
        return vo;
    }

    @Override
    public boolean isFavorite(Long baguwenId) {
        // 获取当前用户ID
        Long userId = userService.getCurrentUserId();
        return favoriteRepository.existsByUserIdAndBaguwenId(userId, baguwenId);
    }

    @Override
    public PageResult<BaguwenFavoriteVO> list(int pageNum, int pageSize) {
        // 获取当前用户ID
        Long userId = userService.getCurrentUserId();
        
        // 创建分页请求
        Pageable pageable = PageRequest.of(pageNum - 1, pageSize, Sort.by(Sort.Direction.DESC, "createTime"));
        
        // 查询带有八股文信息的收藏列表
        Page<BaguwenFavorite> page = favoriteRepository.findAllWithBaguwenByUserId(userId, pageable);
        
        // 转换为VO列表
        List<BaguwenFavoriteVO> voList = page.getContent().stream().map(favorite -> {
            BaguwenFavoriteVO vo = new BaguwenFavoriteVO();
            BeanUtils.copyProperties(favorite, vo);
            vo.setBaguwen(favorite.getBaguwen());
            return vo;
        }).collect(Collectors.toList());
        
        // 返回分页结果
        return new PageResult<>(
                voList,
                page.getTotalElements(),
                pageNum,
                pageSize
        );
    }
} 